package com.inifitness.common.basic;

import java.util.EnumSet;
import java.util.Objects;
import java.util.Optional;

/**
 * 枚举类型接口.
 *
 * @param <T> 枚举值的对象类型
 * @author sunjinfeng
 * @version 1.0.0
 * @since 2024/04/18 11:00:00
 */
public interface BaseEnum<T> {

  /**
   * 根据值获取枚举.
   *
   * @param value 枚举值
   * @param clazz 枚举类型
   * @param <E>   枚举
   * @return 获取到的枚举, 结果可能为null
   */
  static <E extends Enum<E> & BaseEnum<?>> E getEnumByValue(Class<E> clazz, Object value) {
    if (value == null) {
      return null;
    }
    // 获取类型下的所有枚举
    return EnumSet.allOf(clazz).stream()
        .filter(e -> Objects.equals(e.getValue(), value))
        .findFirst()
        .orElse(null);
  }

  /**
   * 根据文本标签获取值
   *
   * @param value 枚举值
   * @param clazz 枚举类型
   * @param <E>   枚举
   * @return 值对应的标签
   */
  static <E extends Enum<E> & BaseEnum<?>> String getLabelByValue(Class<E> clazz,
      Object value) {
    E matchEnum = getEnumByValue(clazz, value);
    return Optional.ofNullable(matchEnum).map(BaseEnum::getLabel).orElse(null);
  }

  /**
   * 根据文本标签获取值
   *
   * @param label 枚举标签
   * @param clazz 枚举类型
   * @param <E>   枚举
   * @return 标签对应的值
   */
  static <E extends Enum<E> & BaseEnum<?>> Object getValueByLabel(String label,
      Class<E> clazz) {
    if (label == null) {
      return null;
    }

    // 获取类型下的所有枚举
    E matchEnum = EnumSet.allOf(clazz).stream()
        .filter(e -> Objects.equals(e.getLabel(), label))
        .findFirst()
        .orElse(null);

    return Optional.ofNullable(matchEnum).map(BaseEnum::getValue).orElse(null);
  }

  T getValue();

  String getLabel();
}
